﻿#include "graphicswidget.h"
#include "ui_graphicswidget.h"
#include <QGraphicsItem>
#include <QDockWidget>
#include <QVBoxLayout>
#include <QPushButton>
#include <QGraphicsTextItem>
#include <QGraphicsPixmapItem>
#include <QDebug>
#include "GraphicsValveItem.h"
#include "GraphicsAirValveItem.h"
#include "Graphics32ValveItem.h"
#include "Graphics42ValveItem.h"
#include "Graphics52ValveItem.h"


GraphicsWidget::GraphicsWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::GraphicsWidget)
{
    ui->setupUi(this);

    scene = new QGraphicsScene(this);

    QGraphicsPixmapItem * pixmapItem = new QGraphicsPixmapItem;
    pixmapItem->setPixmap(QPixmap(u8":/透明背景图.png"));
    scene->addItem(pixmapItem);

    view = new QGraphicsView(this);

    //view->setDragMode(QGraphicsView::ScrollHandDrag);   //互斥：左键拖拽模式
    view->setDragMode(QGraphicsView::RubberBandDrag); //互斥：左键框选模式

    QVBoxLayout *layout = new QVBoxLayout(this);
    layout->setContentsMargins(0, 0, 0, 0);
    layout->addWidget(view);

    //view->resize(2000, 1200);
    view->setSceneRect(QRect(0, 0, 2000, 1200));
    scene->setSceneRect(QRect(0, 0, 2000, 1200));

    //以下固定尺寸改成自动布局
    //view->setFixedSize(2000, 1200);
    view->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);  //视图自适应布局

    //   scene->setBackgroundBrush(QBrush(Qt::darkYellow));
    view->setScene(scene);

    view->scale(0.6, 0.6);

    //scaleRotateDemo();
    valveItemDemo();

}

GraphicsWidget::~GraphicsWidget()
{
    delete ui;
}

void GraphicsWidget::initOpcUA(OpcUA_QThread *OpcUA)
{
    myOpcUA = OpcUA;
}

void GraphicsWidget::updateAllActualValue(double flowmeter[9], double pressuremeter[2], bool valve[11])
{
    m_mfc[0]->setActualValue(flowmeter[0]);
    m_mfc[1]->setActualValue(flowmeter[4]);
    m_mfc[2]->setActualValue(flowmeter[3]);
    m_mfc[3]->setActualValue(flowmeter[2]);
    m_mfc[4]->setActualValue(flowmeter[1]);
    m_mfc[5]->setActualValue(flowmeter[6]);
    m_mfc[6]->setActualValue(flowmeter[5]);
    m_mfc[7]->setActualValue(flowmeter[7]);
    m_mfc[8]->setActualValue(flowmeter[8]);

    m_mfc[9]->setActualValue(pressuremeter[0]);
    m_mfc[10]->setActualValue(pressuremeter[1]);

    airValve[0]->setEnable(valve[0]);
    airValve[1]->setEnable(valve[9]);

    air32Valve[1]->setEnable(valve[1]);
    air32Valve[0]->setEnable(valve[3]);

    m_52Valve[0]->setEnable(valve[2]);
    m_52Valve[1]->setEnable(valve[4]);
    m_52Valve[2]->setEnable(valve[6]);
    m_52Valve[3]->setEnable(valve[8]);

    m_42Valve[0]->setEnable(valve[5]);
    m_42Valve[1]->setEnable(valve[7]);
}

void GraphicsWidget::updateAllDesiredValue(double flowmeter[9], double pressuremeter[2])
{
    m_mfc[0]->setDesiredValue(flowmeter[0]);
    m_mfc[1]->setDesiredValue(flowmeter[4]);
    m_mfc[2]->setDesiredValue(flowmeter[3]);
    m_mfc[3]->setDesiredValue(flowmeter[2]);
    m_mfc[4]->setDesiredValue(flowmeter[1]);
    m_mfc[5]->setDesiredValue(flowmeter[6]);
    m_mfc[6]->setDesiredValue(flowmeter[5]);
    m_mfc[7]->setDesiredValue(flowmeter[7]);
    m_mfc[8]->setDesiredValue(flowmeter[8]);

    m_mfc[9]->setDesiredValue(pressuremeter[0]);
    m_mfc[10]->setDesiredValue(pressuremeter[1]);
}

void GraphicsWidget::scaleRotateDemo()
{
    //initItems();
    initButtons();
}

void GraphicsWidget::valveItemDemo()
{
    QGraphicsTextItem *N2 = new QGraphicsTextItem;
    N2->setTextWidth(150);
    N2->setHtml("<H1>N<sub>2</H1>");
    N2->moveBy(75, 20);
    scene->addItem(N2);

    QGraphicsTextItem *S1 = new QGraphicsTextItem;
    S1->setTextWidth(150);
    S1->setHtml("<H1>S<sub>1</H1>");
    S1->moveBy(205, 20);
    scene->addItem(S1);

    QGraphicsTextItem *S2 = new QGraphicsTextItem;
    S2->setTextWidth(150);
    S2->setHtml("<H1>S<sub>2</H1>");
    S2->moveBy(470, 20);
    scene->addItem(S2);

    m_mfc[0] = new GraphicsMFCItem;
    m_mfc[0]->moveBy(900, 150);
    scene->addItem(m_mfc[0]);

    m_mfc[1] = new GraphicsMFCItem;
    m_mfc[1]->moveBy(201, 311);
    scene->addItem(m_mfc[1]);

    m_mfc[2] = new GraphicsMFCItem;
    m_mfc[2]->moveBy(332, 311);
    scene->addItem(m_mfc[2]);

    m_mfc[3] = new GraphicsMFCItem;
    m_mfc[3]->moveBy(471, 311);
    scene->addItem(m_mfc[3]);

    m_mfc[4] = new GraphicsMFCItem;
    m_mfc[4]->moveBy(599, 311);
    scene->addItem(m_mfc[4]);

    m_mfc[5] = new GraphicsMFCItem;
    m_mfc[5]->moveBy(130, 529);
    scene->addItem(m_mfc[5]);

    m_mfc[6] = new GraphicsMFCItem;
    m_mfc[6]->moveBy(260, 529);
    scene->addItem(m_mfc[6]);

    m_mfc[7] = new GraphicsMFCItem;
    m_mfc[7]->moveBy(390, 529);
    scene->addItem(m_mfc[7]);

    m_mfc[8] = new GraphicsMFCItem;
    m_mfc[8]->moveBy(520, 529);
    scene->addItem(m_mfc[8]);

    m_mfc[9] = new GraphicsMFCItem;
    m_mfc[9]->moveBy(780, 628);
    scene->addItem(m_mfc[9]);

    m_mfc[10] = new GraphicsMFCItem;
    m_mfc[10]->moveBy(780, 742);
    scene->addItem(m_mfc[10]);

    // GraphicsValveItem *valve = new GraphicsValveItem;
    // valve->setToolTip("This is a manual valve");
    // valve->setFlag(QGraphicsItem::ItemIsMovable);
    // valve->moveBy( 87, 915);
    // scene->addItem(valve);

    // valve = new GraphicsValveItem;
    // valve->setFlag(QGraphicsItem::ItemIsMovable);
    // valve->moveBy( 249, 915);
    // scene->addItem(valve);

    // valve = new GraphicsValveItem;
    // valve->setFlag(QGraphicsItem::ItemIsMovable);
    // valve->moveBy( 351, 915);
    // scene->addItem(valve);

    // valve = new GraphicsValveItem;
    // valve->setFlag(QGraphicsItem::ItemIsMovable);
    // valve->moveBy( 509, 915);
    // scene->addItem(valve);

    m_42Valve[0] = new Graphics42ValveItem;
    m_42Valve[0]->moveBy(168, 826);
    m_42Valve[0]->setFlag(QGraphicsItem::ItemIsMovable);
    m_42Valve[0]->setEnable(false);
    scene->addItem(m_42Valve[0]);

    m_42Valve[1] = new Graphics42ValveItem;
    m_42Valve[1]->moveBy(430, 826);
    m_42Valve[1]->setFlag(QGraphicsItem::ItemIsMovable);
    scene->addItem(m_42Valve[1]);

    air32Valve[0] = new Graphics32ValveItem;
    air32Valve[0]->setDir(GraphicsAirValveItem::Down);
    air32Valve[0]->moveBy(207, 203);
    //air32Valve->setFlag(QGraphicsItem::ItemIsMovable);
    scene->addItem(air32Valve[0]);

    air32Valve[1] = new Graphics32ValveItem;
    air32Valve[1]->setDir(GraphicsAirValveItem::Down);
    air32Valve[1]->moveBy(468, 203);
    //air32Valve->setFlag(QGraphicsItem::ItemIsMovable);
    scene->addItem(air32Valve[1]);

    airValve[0] = new GraphicsAirValveItem;
    airValve[0]->moveBy(738, 150);
    airValve[0]->setEnable(false);
    airValve[0]->setDir(GraphicsAirValveItem::Right);
    //airValve[0]->setFlag(QGraphicsItem::ItemIsMovable);
    scene->addItem(airValve[0]);

    airValve[1] = new GraphicsAirValveItem;
    airValve[1]->moveBy(738, 983);
    airValve[1]->setEnable(false);
    airValve[1]->setDir(GraphicsAirValveItem::Right);
    //airValve[1]->setFlag(QGraphicsItem::ItemIsMovable);
    scene->addItem(airValve[1]);

    m_52Valve[0] = new Graphics52ValveItem;
    m_52Valve[0]->moveBy(973, 377);
    m_52Valve[0]->setFlag(QGraphicsItem::ItemIsMovable);
    scene->addItem(m_52Valve[0]);

    m_52Valve[1] = new Graphics52ValveItem;
    m_52Valve[1]->moveBy(973, 468);
    m_52Valve[1]->setFlag(QGraphicsItem::ItemIsMovable);
    scene->addItem(m_52Valve[1]);


    m_52Valve[2] = new Graphics52ValveItem;
    m_52Valve[2]->moveBy(973, 629);
    m_52Valve[2]->setFlag(QGraphicsItem::ItemIsMovable);
    scene->addItem(m_52Valve[2]);

    m_52Valve[3] = new Graphics52ValveItem;
    m_52Valve[3]->moveBy(973, 743);
    m_52Valve[3]->setFlag(QGraphicsItem::ItemIsMovable);
    scene->addItem(m_52Valve[3]);


    m_pump = new GraphicsVacuumPumpItem;
    m_pump->moveBy(1810, 985);
    m_pump->setScale(1);
    //m_pump->setFlag(QGraphicsItem::ItemIsMovable);
    scene->addItem(m_pump);

    //链接mfc仪表的信号与槽
    for (GraphicsMFCItem* item : m_mfc) {
        //遍历每个元素并连接信号，不需要管对象的大小
        connect(item, &GraphicsMFCItem::setPointChanged,
                this, &GraphicsWidget::on_mfcSetPointChanged);
    }

    //链接阀
    connect(air32Valve[0], &Graphics32ValveItem::valveStateChanged, this, &GraphicsWidget::on_valveStateChanged);
    connect(air32Valve[1], &Graphics32ValveItem::valveStateChanged, this, &GraphicsWidget::on_valveStateChanged);
    connect(m_42Valve[0], &Graphics42ValveItem::valveStateChanged, this, &GraphicsWidget::on_valveStateChanged);
    connect(m_42Valve[1], &Graphics42ValveItem::valveStateChanged, this, &GraphicsWidget::on_valveStateChanged);
    for (Graphics52ValveItem* item : m_52Valve) {
        //遍历每个元素并连接信号，不需要管对象的大小
        connect(item, &Graphics52ValveItem::valveStateChanged,
                this, &GraphicsWidget::on_valveStateChanged);
    }
    connect(airValve[0], &GraphicsAirValveItem::valveStateChanged, this, &GraphicsWidget::on_valveStateChanged);
    connect(airValve[1], &GraphicsAirValveItem::valveStateChanged, this, &GraphicsWidget::on_valveStateChanged);

    //链接泵
    connect(m_pump, &GraphicsVacuumPumpItem::pumpStateChanged, this, &GraphicsWidget::on_pumpStateChanged);

}

void GraphicsWidget::pixmapItemDemo()
{
    QGraphicsPixmapItem * pixmapItem;
}

void GraphicsWidget::on_mfcSetPointChanged(double value)
{
    GraphicsMFCItem * p = (GraphicsMFCItem *) sender();

    for (int i = 0; i < 11; ++i) {
        if (p == m_mfc[i])
        {
            qDebug() << u8"m_mfc[" << i << u8"] 状态改变";
            switch (i) {
            case 0:
                myOpcUA->writeFlowRate(1, PLCDataConversion::convert_3000to24576( static_cast<int16_t>(value)) );
                break;
            case 1:
                myOpcUA->writeFlowRate(5, PLCDataConversion::convert_30to24576( static_cast<int16_t>(value)));
                break;
            case 2:
                myOpcUA->writeFlowRate(4, PLCDataConversion::convert_1000to24576( static_cast<int16_t>(value)));
                break;
            case 3:
                myOpcUA->writeFlowRate(3, PLCDataConversion::convert_300to24576( static_cast<int16_t>(value)));
                break;
            case 4:
                myOpcUA->writeFlowRate(2, PLCDataConversion::convert_1000to24576( static_cast<int16_t>(value)));
                break;
            case 5:
                myOpcUA->writeFlowRate(7, PLCDataConversion::convert_100to24576( static_cast<int16_t>(value)));
                break;
            case 6:
                myOpcUA->writeFlowRate(6, PLCDataConversion::convert_1000to24576( static_cast<int16_t>(value)));
                break;
            case 7:
                myOpcUA->writeFlowRate(8, PLCDataConversion::convert_300to24576( static_cast<int16_t>(value)));
                break;
            case 8:
                myOpcUA->writeFlowRate(9, PLCDataConversion::convert_1000to24576( static_cast<int16_t>(value)));
                break;
            case 9:
                myOpcUA->writePressure(1, PLCDataConversion::convert_300to24576( static_cast<int16_t>(value)));
                break;
            case 10:
                myOpcUA->writePressure(2, PLCDataConversion::convert_300to24576( static_cast<int16_t>(value)));
                break;
            }
        }
    }
}

void GraphicsWidget::on_valveStateChanged(bool on)
{
    QObject* p = sender();
    if (!p) return;

    if (GraphicsAirValveItem* valveAir = (GraphicsAirValveItem*)p) {
        //遍历容器查找具体实例
        for (int i = 0; i < 2; ++i) {
            if (airValve[i] == valveAir) {
                qDebug() << u8"airValve[" << i << u8"] 状态改变";
                if( i == 0)
                    myOpcUA->writeValveStatus(1, on);
                else if(i == 1)
                    myOpcUA->writeValveStatus(10, on);
                return;
            }
        }
    }
    if (Graphics32ValveItem* valve32 = (Graphics32ValveItem*)p) {
        //遍历容器查找具体实例
        for (int i = 0; i < 2; ++i) {
            if (air32Valve[i] == valve32) {
                qDebug() << u8"m_32Valve[" << i << u8"] 状态改变";
                if( i == 0)
                    myOpcUA->writeValveStatus(4, on);
                else if(i == 1)
                    myOpcUA->writeValveStatus(2, on);
                return;
            }
        }
    }

    if (Graphics42ValveItem* valve42 = (Graphics42ValveItem*)p) {
        //遍历容器查找具体实例
        for (int i = 0; i < 2; ++i) {
            if (m_42Valve[i] == valve42) {
                qDebug() << u8"m_42Valve[" << i << u8"] 状态改变";
                if( i == 0)
                    myOpcUA->writeValveStatus(6, on);
                else if(i == 1)
                    myOpcUA->writeValveStatus(8, on);
                return;
            }
        }
    }
    if (Graphics52ValveItem* valve52 = (Graphics52ValveItem*)p) {
        //遍历容器查找具体实例
        for (int i = 0; i < 4; ++i) {
            if (m_52Valve[i] == valve52) {
                qDebug() << u8"m_52Valve[" << i << u8"] 状态改变";
                if( i == 0)
                    myOpcUA->writeValveStatus(3, on);
                else if(i == 1)
                    myOpcUA->writeValveStatus(5, on);
                else if(i == 2)
                    myOpcUA->writeValveStatus(7, on);
                else if(i == 3)
                    myOpcUA->writeValveStatus(9, on);
                return;
            }
        }
    }
}

void GraphicsWidget::on_pumpStateChanged(bool on)
{
    //还不知道信号对应PLC的哪个点位
}

void GraphicsWidget::initItems()
{
    QPen pen; // 定义一个画笔，设置画笔颜色和宽度
    pen.setColor(QColor(0, 160, 230));
    pen.setWidth(10);

    QGraphicsRectItem *rectItem = new QGraphicsRectItem(); // 定义一个矩形图
    rectItem->setRect(0, 0, 80, 80);
    rectItem->setPen(pen);
    rectItem->setBrush(QBrush(QColor(255, 255, 255)));
    rectItem->setFlag(QGraphicsItem::ItemIsMovable);
    scene->addItem(rectItem); // 把矩形图元添加到场景

    rectItem->moveBy(100, 200);
}

void GraphicsWidget::initButtons()
{
    QPushButton *RightButton = new QPushButton("Right");
    QPushButton *UpButton = new QPushButton("Up");
    QPushButton *DownButton = new QPushButton("Down");
    QPushButton *LeftButton = new QPushButton("Left");

    QDockWidget * dockWidget = new QDockWidget(this);
    QVBoxLayout * layout = new QVBoxLayout(dockWidget);
    layout->addWidget(RightButton);
    layout->addWidget(LeftButton);
    layout->addWidget(UpButton);
    layout->addWidget(DownButton);

    QPushButton *onButton = new QPushButton("On");
    QPushButton *offButton = new QPushButton("Off");
    layout->addWidget(onButton);
    layout->addWidget(offButton);
    layout->addStretch();

    QWidget *widget = new QWidget;

    widget->setLayout(layout);
    dockWidget->setWidget(widget);

    //addDockWidget(Qt::RightDockWidgetArea, dockWidget);


    // QObject::connect(zoomInButton, &QPushButton::clicked, [&]() { view->scale(1.2, 1.2); });
    // QObject::connect(zoomOutButton, &QPushButton::clicked, [&]() { view->scale(0.8, 0.8); });
    // QObject::connect(rotateLeftButton, &QPushButton::clicked, [&]() { view->rotate(-10);});
    //QObject::connect(rotateRightButton, &QPushButton::clicked, [&]() { view->rotate(10);});
    QObject::connect(LeftButton, &QPushButton::clicked, [&]() { air32Valve[1]->setDir(Graphics32ValveItem::Left);});
    QObject::connect(RightButton, &QPushButton::clicked, [&]() { air32Valve[1]->setDir(Graphics32ValveItem::Right); });
    QObject::connect(UpButton, &QPushButton::clicked, [&]() { air32Valve[1]->setDir(Graphics32ValveItem::Up); });
    QObject::connect(DownButton, &QPushButton::clicked, [&]() { air32Valve[1]->setDir(Graphics32ValveItem::Down);});


    // QObject::connect(rotateRightButton, &QPushButton::clicked, [&]() { airValve->setRotation(90);});
    // QObject::connect(zoomInButton, &QPushButton::clicked, [&]() { airValve->setRotation(180); });
    // QObject::connect(zoomOutButton, &QPushButton::clicked, [&]() { airValve->setRotation(270); });
    // QObject::connect(rotateLeftButton, &QPushButton::clicked, [&]() { airValve->setRotation(0);});

    QObject::connect(onButton, &QPushButton::clicked, [&]() { air32Valve[1]->setEnable(true);});
    QObject::connect(offButton, &QPushButton::clicked, [&]() { air32Valve[1]->setEnable(false);});
}
/*
 * 下方代码写了后，会不显示图像。
void GraphicsWidget::resizeEvent(QResizeEvent *event)
{
    QSize s = event->size();

    double x_scale = s.width() / 2000;
    double y_scale = s.height() / 1200;
    if(x_scale < y_scale)
    {
        view->scale(x_scale, x_scale);
    }
    else
    {
        view->scale(y_scale, y_scale);
    }
}
*/

